(module iterator-interface mzscheme

  (require "../private/require.ss")
  (require-contracts)
  (require-class)

  (provide iterator<%> iterator/c iterator?
           indexed-iterator<%> indexed-iterator/c indexed-iterator?
           counted-iterator<%> counted-iterator/c counted-iterator?
           )

  ;; iterator<%> : Interface
  ;; The interface for objects of type (Iterator Elem) for any type Elem,
  ;; representing iterators over collections of any element type.
  (define iterator<%>
    (interface ()

      ;; (send (Iterator Elem) end?) : Boolean
      ;; Reports whether the iterator has reached the end.
      end?

      ;; (send (Iterator Elem) element) : Elem
      ;; Produces the element at the iterator's current position.
      ;; It is an error if the iterator is at the end of the collection.
      element

      ;; (send (Iterator Elem) next) : (Iterator Elem)
      ;; Produces an iterator at the next position.
      ;; It is an error if the iterator is at the end of the collection.
      next

      ))

  ;; iterator/c : FlatContract
  ;; Recognizes iterators.
  (define iterator/c (is-a?/c iterator<%>))

  ;; iterator? : Any -> Boolean
  ;; Reports whether a value is an iterator.
  (define (iterator? v)
    (is-a? v iterator<%>))

  ;; indexed-iterator<%> : Interface
  ;; The interface for objects of type (IndexedIterator Key Elem)
  ;; representing iterators over indexed collections with the given
  ;; key and element types.
  ;; An (IndexedIterator Key Elem) is also an (Iterator Elem).
  (define indexed-iterator<%>
    (interface (iterator<%>)

      ;; (send (IndexedIterator Key Elem) key) : Key
      ;; Produces the key at the iterator's current position.
      ;; It is an error if the iterator is at the end of the collection.
      key

      ))

  ;; indexed-iterator/c : FlatContract
  ;; Recognizes indexed iterators.
  (define indexed-iterator/c (is-a?/c indexed-iterator<%>))

  ;; indexed-iterator? : Any -> Boolean
  ;; Reports whether a value is an indexed iterator.
  (define (indexed-iterator? v)
    (is-a? v indexed-iterator<%>))
  
  ;; counted-iterator<%> : Interface
  ;; The interface for objects of type (CountedIterator Elem)
  ;; representing iterators over collections where elements
  ;; of the given type have a count of the number of appearances
  ;; in the collection.
  ;; A (CountedIterator Elem) is also an (Iterator Elem).
  (define counted-iterator<%>
    (interface (iterator<%>)
      
      ;; (send (CountedIterator Elem) count) : Integer
      ;; Produces the count for the current element.
      ;; It is an error if the iterator is at the end of the collection.
      count
      
      ))
  
  ;; counted-iterator/c: FlatContract
  ;; Recognizes counted iterators.
  (define counted-iterator/c (is-a?/c counted-iterator<%>))
  
  ;; counted-iterator? : Any -> Boolean
  ;; Reports whether a value is a counted iterator.
  (define (counted-iterator? v)
    (is-a? v counted-iterator<%>))

  )